package de.rs.espresso;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import de.rs.espresso.cubes.CubeFactory;
import de.rs.espresso.cubes.CubeFactory.CubeRepresentation;
import de.rs.espresso.interfaces.ICover;
import de.rs.espresso.interfaces.IProblem;
import de.rs.espresso.interfaces.IProblemProvider;
import de.rs.espresso.interfaces.IResult;
import de.rs.espresso.problemprovider.BLIFFileExtractor;
import de.rs.espresso.problems.LogicalMinimizationProblem;
import de.rs.espresso.tools.Statistics;

public class BLIFMinimizer {
	
	private static final boolean DEMO = false;

	private static final int NUMBER_OF_THREADS = 1;

	private static final boolean USE_THREAD_POOL = false;

	private static long id;

	private File bFile;

	public BLIFMinimizer(File bFile) {
		this.bFile = bFile;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		id = Statistics.startMeasurement("OVERALL");

		CubeFactory.setCubeRepresentation(CubeRepresentation.LONG);

		File bFile;

		if (args.length == 0) {
			bFile = new File("C:\\Users\\Jan\\Downloads\\blif\\");
			//bFile = new File("C:\\Users\\Jan\\Desktop\\small.blif");
		} else {
			bFile = new File(args[0]);
		}

		if (bFile.isDirectory()) {
			for (String s : bFile.list()) {
				File f = new File(bFile.getAbsolutePath() + "/" + s);
				if (f.isFile() && s.endsWith(".blif")
						&& !s.endsWith("_minimized.blif") && !s.endsWith("_sis.blif")) {
					BLIFMinimizer bm = new BLIFMinimizer(f);
					bm.start();
				}
			}
		} else {
			BLIFMinimizer bm = new BLIFMinimizer(bFile);
			bm.start();
		}

		Statistics.stopMeasurement(id);
		System.out.println("Max performed main loop cycles = "+LogicalMinimizationProblem.maxLoop);
		Statistics.printStatistics();

		if(!DEMO)
			System.exit(0);

	}

	public void start() {
		IProblemProvider sbp = new BLIFFileExtractor();

		try {
			//System.out.println("Processing " + bFile.getName() + "...");
			// import the BLIF file...
			sbp.importFile(bFile);
			// .. and parse it.
			sbp.parse();

			List<IProblem> pList = sbp.getProblems();
			ArrayList<IResult> resultList = new ArrayList<IResult>();
			


			if (USE_THREAD_POOL) {

				ExecutorService es = Executors
						.newFixedThreadPool(NUMBER_OF_THREADS);

				ArrayList<SolverThread> threadList = new ArrayList<SolverThread>();

				for (IProblem p : pList)
					threadList.add(new SolverThread(p));

				List<Future<IResult>> futureList = es.invokeAll(threadList);

				resultList = new ArrayList<IResult>();

				for (Future<IResult> future : futureList) {
					resultList.add(future.get());
				}

				es.shutdown();

			} else {
				for (IProblem p : pList) {
					if(DEMO) {
						if (pList.size()==1)
							p.demo();
					}
					p.solve();
					resultList.add(p.getResult());
				}
			}

			sbp.writeBack(resultList);

		} catch (IOException e) {

			e.printStackTrace();

		} catch (ParseException e) {

			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		
		

	}

}
